package com.sammier.snake;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Random;

//游戏的面板
public class GamePanel extends JPanel implements KeyListener, ActionListener {

    //定义🐍的数据结构
    int length;//🐍的长度
    int [] snakeX = new int [600];//🐍的x坐标  25*25
    int [] snakeY = new int [500];//🐍的y坐标  25*25
    String fx ;//初始方向向右

    //食物的坐标
    int foodX;
    int foodY;
    int good_apple_X;
    int good_apple_Y;
    int bad_apple_X;
    int bad_apple_Y;
    Random random = new Random();

    //初始化成绩
    int score;

    //游戏当前状态：开始，停止
    boolean isStart = false; //默认是不开始
    boolean isFail = false;//游戏失败

    //定时器 以毫秒为单位 1000ms = 1s
    Timer timer = new Timer(100, this); // 100毫秒执行一次！

    //加速状态
    boolean isSpeedUp = false;
    int speedUpTimer = 0;

    //构造器
    public GamePanel() {
        init();
        //获取焦点和键盘事件
        this.setFocusable(true);//获得焦点事件
        this.addKeyListener(this);//获得键盘监听事件
        timer.start(); //游戏一开始定时器就启动
        this.requestFocusInWindow();// 重要：确保键盘事件生效
    }
    //初始化方法
    public void init(){
        length = 3;
        snakeX[0] = 100; snakeY[0] = 100;//head 坐标
        snakeX[1] = 75; snakeY[1] = 100;//第一个身体坐标
        snakeX[2] = 50; snakeY[2] = 100;//第二个body坐标
        fx = "R";
        //把食物随机分布在界面上
        foodX = 25 + 25*random.nextInt(34);
        foodY = 75 + 25*random.nextInt(24);
        //好苹果🍎
        good_apple_X = 25 + 25*random.nextInt(34);
        good_apple_Y = 75 + 25*random.nextInt(24);
        //坏苹果🍎
        bad_apple_X = 25 + 25*random.nextInt(34);
        bad_apple_Y = 75 + 25*random.nextInt(24);
        score = 0;
    }

    //绘制面板，所有东西都用画笔来画
    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);//清屏
        //绘制静态面板
        Data.header.paintIcon(this, g, 11, 11);//头部广告栏
        g.fillRect(25,75,850,600);//默认的游戏界面
        this.setBackground(Color.WHITE);

        //画积分
        g.setColor(Color.WHITE);
        g.setFont(new Font("Times New Roman", Font.BOLD, 20));
        g.drawString("Score: " + score, 750, 35);
        g.drawString("Length"+length,750,55);

        //画食物
        Data.food.paintIcon(this,g,foodX,foodY);
        //好苹果
        Data.good_apple.paintIcon(this,g,good_apple_X,good_apple_Y);
        //坏🍎
        Data.bad_apple.paintIcon(this,g,bad_apple_X,bad_apple_Y);

        //把小蛇画上去
        if (fx.equals("R")){
            Data.right.paintIcon(this,g,snakeX[0],snakeY[0]); // 脑袋方向
        }else if (fx.equals("L")){
            Data.left.paintIcon(this,g,snakeX[0],snakeY[0]);
        }else if (fx.equals("U")){
            Data.up.paintIcon(this,g,snakeX[0],snakeY[0]);
        }else if (fx.equals("D")){
            Data.down.paintIcon(this,g,snakeX[0],snakeY[0]);
        }
        for (int i = 1; i < length; i++) {
            Data.body.paintIcon(this,g,snakeX[i],snakeY[i]); //🐍身体
        }

        //游戏状态
        if (isStart == false){
            g.setColor(Color.WHITE);
            g.setFont(new Font("微软雅黑",Font.BOLD,40));//设置字体
            g.drawString("按下空格开始游戏",300,300);
        }
        if (isFail){
            g.setColor(Color.RED);
            g.setFont(new Font("微软雅黑",Font.BOLD,40));//设置字体
            g.drawString("失败，按下空格重新开始游戏",300,300);
        }
    }



    //键盘监听事件
    @Override
    public void keyPressed(KeyEvent e) {
        int keyCode = e.getKeyCode();//获得键盘按键是哪一个
        if (keyCode == KeyEvent.VK_SPACE){ //如果是空格
            if (isFail){
                //重新开始
                init();
                isFail = false;
            }else {
                isStart = !isStart;//取反
            }
            //System.out.println("空格按下 ，isStart=" + isStart);
            repaint();
        }
        //🐍移动
        if (keyCode == KeyEvent.VK_LEFT){
            fx = "L";
        }else if (keyCode == KeyEvent.VK_RIGHT){
            fx = "R";
        }else if (keyCode == KeyEvent.VK_UP){
            fx = "U";
        }else if (keyCode == KeyEvent.VK_DOWN){
            fx = "D";
        }

        /*
            vscode新增方向控制逻辑（否则无法看到移动效果）
             && !fx.equals("R") 这样的逻辑是 防止小蛇直接掉头。
         */
        /*
            else if (keyCode == KeyEvent.VK_LEFT && !fx.equals("R")) {
            fx = "L";
        } else if (keyCode == KeyEvent.VK_RIGHT && !fx.equals("L")) {
            fx = "R";
        } else if (keyCode == KeyEvent.VK_UP && !fx.equals("D")) {
            fx = "U";
        } else if (keyCode == KeyEvent.VK_DOWN && !fx.equals("U")) {
            fx = "D";
        }
         */


    }

    //事件监听   1s 10次
    @Override
    public void actionPerformed(ActionEvent e) {
        if(isStart && isFail == false){ //如果游戏是开始状态，就让🐍动起来

            //吃食物
            if (snakeX[0] == foodX && snakeY[0] == foodY){
                length++; // 长度加一
                score += 10;//分数加10
                //再次随机食物
                foodX = 25 + 25*random.nextInt(34);
                foodY = 75 + 25*random.nextInt(24);

            }
            //好🍎
            if (snakeX[0] == good_apple_X && snakeY[0] == good_apple_Y){
                length += 3; // 长度加3
                score += 30;//分数加10
                //再次随机食物
                good_apple_X = 25 + 25*random.nextInt(34);
                good_apple_Y = 75 + 25*random.nextInt(24);

                //启动加速
                isSpeedUp = true;
                speedUpTimer += 3000; //累计加速时间
                timer.setDelay(50);//加速
                Timer newSpeedUpTimer = new Timer(speedUpTimer, new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        speedUpTimer -= 3000;//减去已处理的加速时间
                        if (speedUpTimer <= 0){
                            isSpeedUp = false;
                            timer.setDelay(100);//恢复正常速度
                        }
                        ((Timer)e.getSource()).stop();//停止当前定时器
                    }
                });
                newSpeedUpTimer.setRepeats(false);//计时器只执行一次
                newSpeedUpTimer.start();

            }
            //坏🍎
            if (snakeX[0] == bad_apple_X && snakeY[0] == bad_apple_Y){
                length -= 3; // 长度加3
                score -= 30;//分数加10
                //再次随机食物
                bad_apple_X = 25 + 25*random.nextInt(34);
                bad_apple_Y = 75 + 25*random.nextInt(24);
                if (length <=0 |score < 0){
                    isFail = true;
                }
            }

            //🐍移动
            for (int i = length-1; i >0 ; i--) {
                snakeX[i] = snakeX[i-1];//向前移一节
                snakeY[i] = snakeY[i-1];
            }
            //走向
            if (fx.equals("R")){
                snakeX[0] = snakeX [0]+25;
                if (snakeX[0]>850){ snakeX[0] = 25;} //边界判断
            }else if (fx.equals("L")){
                snakeX[0] = snakeX [0]-25;
                if (snakeX[0]<25){ snakeX[0] = 850;} //边界判断
            }else if (fx.equals("U")){
                snakeY[0] = snakeY [0]-25;
                if (snakeY[0]<75){ snakeY[0] = 650;} //边界判断
            }else if (fx.equals("D")){
                snakeY[0] = snakeY [0]+25;
                if (snakeY[0]>650){ snakeY[0] = 75;} //边界判断
            }

            //失败判断，撞到自己就算失败
            for (int i = 1; i <length ; i++) {
                if (snakeX[0]==snakeX[i] && snakeY[0]==snakeY[i]){
                    isFail = true;
                }
            }
            repaint();//重画页面
        }
        timer.start(); //定时器开启
    }


    @Override
    public void keyReleased(KeyEvent e) {}
    @Override
    public void keyTyped(KeyEvent e) {}
}



